<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>函数扩展 | Awesome-笔记</title>
    <meta name="generator" content="VuePress 1.9.10">
    <link rel="icon" href="icons/favicon.ico">
    <meta name="description" content="">
    <meta name="author" content="热爱生活，喜欢睡觉">
    <meta name="about" content="这是一个专门用于记录笔记的静态资源网站">
    
    <link rel="preload" href="/awesome-notebook/assets/css/0.styles.ad5756f5.css" as="style"><link rel="preload" href="/awesome-notebook/assets/js/app.5520c9b0.js" as="script"><link rel="preload" href="/awesome-notebook/assets/js/2.778bb4ad.js" as="script"><link rel="preload" href="/awesome-notebook/assets/js/1.50b457b8.js" as="script"><link rel="preload" href="/awesome-notebook/assets/js/25.dedb1585.js" as="script"><link rel="prefetch" href="/awesome-notebook/assets/js/10.325b9f09.js"><link rel="prefetch" href="/awesome-notebook/assets/js/11.c62b6b34.js"><link rel="prefetch" href="/awesome-notebook/assets/js/12.ecdb524b.js"><link rel="prefetch" href="/awesome-notebook/assets/js/13.3f3f6a36.js"><link rel="prefetch" href="/awesome-notebook/assets/js/14.eb7a3d07.js"><link rel="prefetch" href="/awesome-notebook/assets/js/15.114dfd5c.js"><link rel="prefetch" href="/awesome-notebook/assets/js/16.85253907.js"><link rel="prefetch" href="/awesome-notebook/assets/js/17.c2838453.js"><link rel="prefetch" href="/awesome-notebook/assets/js/18.3256f17f.js"><link rel="prefetch" href="/awesome-notebook/assets/js/19.d8afd0ae.js"><link rel="prefetch" href="/awesome-notebook/assets/js/20.10e47ab9.js"><link rel="prefetch" href="/awesome-notebook/assets/js/21.33b300c9.js"><link rel="prefetch" href="/awesome-notebook/assets/js/22.b7c97fbe.js"><link rel="prefetch" href="/awesome-notebook/assets/js/23.e9994ecc.js"><link rel="prefetch" href="/awesome-notebook/assets/js/24.8cc3e1e8.js"><link rel="prefetch" href="/awesome-notebook/assets/js/26.9422829f.js"><link rel="prefetch" href="/awesome-notebook/assets/js/27.9802cd87.js"><link rel="prefetch" href="/awesome-notebook/assets/js/28.d9f287bc.js"><link rel="prefetch" href="/awesome-notebook/assets/js/29.dc9b14bd.js"><link rel="prefetch" href="/awesome-notebook/assets/js/3.af33e5d6.js"><link rel="prefetch" href="/awesome-notebook/assets/js/30.645d0efa.js"><link rel="prefetch" href="/awesome-notebook/assets/js/31.164808cf.js"><link rel="prefetch" href="/awesome-notebook/assets/js/32.59287e4c.js"><link rel="prefetch" href="/awesome-notebook/assets/js/33.3031be3e.js"><link rel="prefetch" href="/awesome-notebook/assets/js/34.4ce6ff0d.js"><link rel="prefetch" href="/awesome-notebook/assets/js/35.d58eebcc.js"><link rel="prefetch" href="/awesome-notebook/assets/js/4.45665f8a.js"><link rel="prefetch" href="/awesome-notebook/assets/js/5.7098d77a.js"><link rel="prefetch" href="/awesome-notebook/assets/js/6.0c0a0f39.js"><link rel="prefetch" href="/awesome-notebook/assets/js/7.6a854e57.js"><link rel="prefetch" href="/awesome-notebook/assets/js/vendors~docsearch.5e19b665.js">
    <link rel="stylesheet" href="/awesome-notebook/assets/css/0.styles.ad5756f5.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/awesome-notebook/" class="home-link router-link-active"><img src="/awesome-notebook/imgs/hero.png" alt="Awesome-笔记" class="logo"> <span class="site-name can-hide">Awesome-笔记</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/awesome-notebook/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="三件套" class="dropdown-title"><span class="title">三件套</span> <span class="arrow down"></span></button> <button type="button" aria-label="三件套" class="mobile-dropdown-title"><span class="title">三件套</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          css
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/css/css学习.html" class="nav-link">
  css笔记
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/css/css面试题.html" class="nav-link">
  css面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          js
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/es6语法学习.html" class="nav-link">
  es6语法学习
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js常用操作.html" class="nav-link">
  js常用操作
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js面试题.html" class="nav-link">
  js面试题
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js数据对象及API.html" class="nav-link">
  js常用API
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js_knowledge_1.html" class="nav-link">
  其他js知识
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="服务端" class="dropdown-title"><span class="title">服务端</span> <span class="arrow down"></span></button> <button type="button" aria-label="服务端" class="mobile-dropdown-title"><span class="title">服务端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/服务端/express框架.html" class="nav-link">
  express框架
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="工程化" class="dropdown-title"><span class="title">工程化</span> <span class="arrow down"></span></button> <button type="button" aria-label="工程化" class="mobile-dropdown-title"><span class="title">工程化</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          vue相关
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/工程化/vue/vue2笔记.html" class="nav-link">
  vue2笔记
</a></li></ul></li><li class="dropdown-item"><h4>
          webpack相关
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/工程化/webpack相关/webpack使用.html" class="nav-link">
  wepack笔记
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="开发工具" class="dropdown-title"><span class="title">开发工具</span> <span class="arrow down"></span></button> <button type="button" aria-label="开发工具" class="mobile-dropdown-title"><span class="title">开发工具</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/开发工具/git笔记.html" class="nav-link">
  git笔记
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="小程序" class="dropdown-title"><span class="title">小程序</span> <span class="arrow down"></span></button> <button type="button" aria-label="小程序" class="mobile-dropdown-title"><span class="title">小程序</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/小程序相关/微信小程序笔记.html" class="nav-link">
  微信小程序原生
</a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/awesome-notebook/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="三件套" class="dropdown-title"><span class="title">三件套</span> <span class="arrow down"></span></button> <button type="button" aria-label="三件套" class="mobile-dropdown-title"><span class="title">三件套</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          css
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/css/css学习.html" class="nav-link">
  css笔记
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/css/css面试题.html" class="nav-link">
  css面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          js
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/es6语法学习.html" class="nav-link">
  es6语法学习
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js常用操作.html" class="nav-link">
  js常用操作
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js面试题.html" class="nav-link">
  js面试题
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js数据对象及API.html" class="nav-link">
  js常用API
</a></li><li class="dropdown-subitem"><a href="/awesome-notebook/三件套/js/js_knowledge_1.html" class="nav-link">
  其他js知识
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="服务端" class="dropdown-title"><span class="title">服务端</span> <span class="arrow down"></span></button> <button type="button" aria-label="服务端" class="mobile-dropdown-title"><span class="title">服务端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/服务端/express框架.html" class="nav-link">
  express框架
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="工程化" class="dropdown-title"><span class="title">工程化</span> <span class="arrow down"></span></button> <button type="button" aria-label="工程化" class="mobile-dropdown-title"><span class="title">工程化</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          vue相关
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/工程化/vue/vue2笔记.html" class="nav-link">
  vue2笔记
</a></li></ul></li><li class="dropdown-item"><h4>
          webpack相关
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/awesome-notebook/工程化/webpack相关/webpack使用.html" class="nav-link">
  wepack笔记
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="开发工具" class="dropdown-title"><span class="title">开发工具</span> <span class="arrow down"></span></button> <button type="button" aria-label="开发工具" class="mobile-dropdown-title"><span class="title">开发工具</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/开发工具/git笔记.html" class="nav-link">
  git笔记
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="小程序" class="dropdown-title"><span class="title">小程序</span> <span class="arrow down"></span></button> <button type="button" aria-label="小程序" class="mobile-dropdown-title"><span class="title">小程序</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/awesome-notebook/小程序相关/微信小程序笔记.html" class="nav-link">
  微信小程序原生
</a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>函数扩展</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#函数参数-的默认值" class="sidebar-link">函数参数 的默认值</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#属性简洁写法" class="sidebar-link">属性简洁写法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#基本用法" class="sidebar-link">基本用法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#then-函数" class="sidebar-link">then 函数</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#then-指定的回调函数调用时机" class="sidebar-link">then 指定的回调函数调用时机</a></li></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#promise-实现-ajax" class="sidebar-link">Promise 实现 ajax</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#catch-方法" class="sidebar-link">catch 方法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#promise-all" class="sidebar-link">Promise.all</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#constructor-方法" class="sidebar-link">constructor 方法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#实例属性" class="sidebar-link">实例属性</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#handler-函数方法" class="sidebar-link">handler 函数方法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#get" class="sidebar-link">get</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#set" class="sidebar-link">set</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#has" class="sidebar-link">has</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#defineproperty" class="sidebar-link">defineProperty</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#deleteproperty" class="sidebar-link">deleteProperty</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#reflect-对象静态方法" class="sidebar-link">Reflect 对象静态方法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#apply-方法" class="sidebar-link">apply 方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#construct-方法" class="sidebar-link">construct 方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#defineproperty-方法" class="sidebar-link">defineProperty 方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#deleteproperty-方法" class="sidebar-link">deleteProperty()方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#getprototypeof-方法" class="sidebar-link">getPrototypeOf 方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#get-方法" class="sidebar-link">get()方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#set-方法" class="sidebar-link">set()方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#has-方法" class="sidebar-link">has()方法</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#ownkeys-方法" class="sidebar-link">ownKeys()方法</a></li></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#实例-观察者模式" class="sidebar-link">实例：观察者模式</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#yield-表达式" class="sidebar-link">yield 表达式</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#next-方法" class="sidebar-link">next()方法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#es6-模块设计初衷" class="sidebar-link">es6 模块设计初衷</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#export-命令" class="sidebar-link">export 命令</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#import-语句" class="sidebar-link">import 语句</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#注意-关于-export-和-import-方法名一致的问题" class="sidebar-link">注意：关于 export 和 import 方法名一致的问题</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#其他注意事项" class="sidebar-link">其他注意事项</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#模块的整体加载" class="sidebar-link">模块的整体加载</a></li><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#export-与-import-混合使用" class="sidebar-link">export 与 import 混合使用</a></li></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#export-default-命令" class="sidebar-link">export default 命令</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#import" class="sidebar-link">import()</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/awesome-notebook/%E4%B8%89%E4%BB%B6%E5%A5%97/js/es6%E8%AF%AD%E6%B3%95%E5%AD%A6%E4%B9%A0.html#引入背景" class="sidebar-link">引入背景</a></li></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="函数扩展"><a href="#函数扩展" class="header-anchor">#</a> 函数扩展</h1> <h2 id="函数参数-的默认值"><a href="#函数参数-的默认值" class="header-anchor">#</a> 函数参数 的默认值</h2> <ul><li>es6 之前函数参数默认值的写法</li> <li>缺点：如果为参数 name 赋值为 false，该赋值不会起作用，为此，可改进代码写法：检查参数 name 是否为 undefined</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  name <span class="token operator">=</span> name <span class="token operator">||</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>
  <span class="token comment">//改进写法</span>
  <span class="token comment">// if(typeof name===&quot;undefined&quot;){name=&quot;张三&quot;}</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">我的名字是</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>es6 之后，可以直接将值写在函数参数的后面作为其默认值</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">我的名字是</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>函数参数是默认声明的,不允许使用<code>let、const</code>再次声明</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">x <span class="token operator">=</span> <span class="token number">5</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// error</span>
  <span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// error</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>与解构赋值结合使用</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> name<span class="token punctuation">,</span> age <span class="token operator">=</span> <span class="token number">10</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> age<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>上面代码中只有当函数 foo()的实参是一个对象时，变量 name/age 才能够通过解构赋值生成</p></blockquote> <blockquote><p>如果 foo()调用没有提供参数，变量 name/age 就不会生成,从而报错。因此可以给函数参数设置一个空对象作为默认值，来避免报错</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> name<span class="token punctuation">,</span> age <span class="token operator">=</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> age<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>上面代码中，如果调用 foo 函数时提供了一个对象作为参数，并且该对象有一个 age 属性，那么 age 变量将被赋值为该属性的值。
如果调用 foo 函数时没有提供任何参数，或者提供的对象没有 age 属性，那么 age 变量将被赋值为 10</p></blockquote> <h1 id="对象扩展"><a href="#对象扩展" class="header-anchor">#</a> 对象扩展</h1> <h2 id="属性简洁写法"><a href="#属性简洁写法" class="header-anchor">#</a> 属性简洁写法</h2> <ul><li>在大括号内直接写入变量和函数作为对象的属性和方法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> str <span class="token operator">=</span> <span class="token string">&quot;hello world&quot;</span><span class="token punctuation">;</span>
<span class="token comment">/*变量直接写在大括号中，属性名就是变量名，属性值就是变量值*/</span>
<span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> str <span class="token punctuation">}</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{str:'hello world'}</span>
</code></pre></div><h1 id="promise-对象"><a href="#promise-对象" class="header-anchor">#</a> Promise 对象</h1> <ul><li><p>promise 对象实质上是一个容器，代表一个异步操作，其具有三种状态：pending（进行中）、fulfilled（已成功）、rejected（已失败），异步操作的结果，决定当前状态，其他任何操作都不能改变该状态</p></li> <li><p>promise 对象的状态改变后就不会再变了，改变的结果只有两种：pending&gt;&gt;fulfilled 、 pending&gt;&gt;rejected，此时就称 promise 对象定型了（rejected）。</p></li> <li><p>有了 Promise 对象，异步操作就可以以同步操作的流程表达出来，避免了嵌套的回调函数</p></li></ul> <h2 id="基本用法"><a href="#基本用法" class="header-anchor">#</a> 基本用法</h2> <ul><li>Promise 构造函数接受一个函数作为参数，该函数的两个参数分别为 resolve 和 reject,两者也是函数</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 要做的事情...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li><p>resolve 函数：将 Promise 对象的状态从 pending 转化为 fulfilled，在异步操作成功时调用，并将异步操作结果作为参数传递出来</p></li> <li><p>reject 函数：将 Promise 对象的状态从 pending 转化为 rejected，在异步操作失败时调用，并将异步操作报出的错误作为参数传递出来</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// ... some code</span>

  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token comment">/* 异步操作成功 */</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token function">resolve</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment">//异步操作成功，调用 resolve 函数传递成功的结果</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment">//异步操作失败，调用 reject 函数传递失败的原因</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>一般来说，调用<code>resolve或reject</code>之后，Promise 的使命就完成了，后续的操作应该放在 then 方法或 catch 方法中，但是，调用<code>resolve或reject</code>并不会终结 Promise 的参数函数的执行，所以一般在两者的前面加上 return 语句</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">r</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 2</span>
<span class="token comment">// 1</span>
</code></pre></div><blockquote><p>上面代码中，调用 resolve(1)以后，后面的 console.log(2)还是会执行，并且会首先打印出来</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 后面的语句不会执行</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>上面代码中，调用 resolve 函数后终止函数的执行</p></blockquote> <ul><li>调用 resolve 函数和 reject 函数时带有参数，那么它们的参数会被传递给回调函数</li> <li>reject 函数的参数通常是==Error 对象的实例==，表示抛出的错误；resolve 函数的参数除了==正常的值==以外，还可能是==另一个 Promise 实例==</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">&quot;fail&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">resolve</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

p2<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;执行了then&quot;</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;执行了catch&quot;</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 执行了catch Error: fail</span>
</code></pre></div><blockquote><p>从上面代码的执行结果我们可以看到，p2 作为 Promise 实例，其 catch 执行了，说明一定是由于 Promise 对象的状态由'pending'&gt;&gt;&gt;'rejected'导致的
从头分析，1s 之后，由于调用 resolve 函数，p2 的状态变为 resolved,但是由于 p2 返回的是另一个 Promise，导致 p2 自己的状态无效了，p1 的状态决定 p2 的状态，p1 此时状态为 pending，p2 的回调函数就会等待 p1 的状态改变。
3s 时，p1 变为 rejected，导致触发 catch 方法指定的回调函数</p></blockquote> <h3 id="then-函数"><a href="#then-函数" class="header-anchor">#</a> then 函数</h3> <p>实例化过的 promise 对象可调用 then 方法，为 Promise 实例添加状态改变时的回调函数</p> <div class="language-js extra-class"><pre class="language-js"><code>promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>onFulfilled<span class="token punctuation">,</span> onRejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//或</span>
promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>onFulfilled<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>onRejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>then()方法可接受两个回调函数作为参数</li> <li>第一个参数：promise 对象的状态变为 resolved（fulfilled） 状态时应执行的回调函数</li> <li>第二个参数：promise 对象的状态变为 rejected 状态时应执行的回调函数</li> <li>返回值：一个新的 Promise 实例（可以采用链式写法，即 then 方法后面再调用另一个 then 方法）</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">timeout</span><span class="token punctuation">(</span><span class="token parameter">delay</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token function">setTimeout</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> delay<span class="token punctuation">,</span> <span class="token string">&quot;done&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">timeout</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// &quot;done&quot;</span>
</code></pre></div><blockquote><p>上面代码中，<code>setTimeout(resolve, delay, &quot;done&quot;);</code>意味着经过 delay 毫秒的延迟之后，执行 resolve 函数，将 Promise 的状态从 pending 转化为 fulfilled，触发 then 方法绑定的回调函数</p></blockquote> <blockquote><p>其中的&quot;done&quot;作为参数传递给 resolve 函数，相当于 resolve(&quot;done&quot;)，而 resolve 函数调用时传递的参数又会被传递给 then 方法中的回调函数，于是最终通过 console.log 打印出来</p></blockquote> <h3 id="then-指定的回调函数调用时机"><a href="#then-指定的回调函数调用时机" class="header-anchor">#</a> then 指定的回调函数调用时机</h3> <ul><li>Promise 新建后立即执行</li> <li>then 方法指定的回调函数，在当前脚本所有同步任务执行完后才会执行</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Promise&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;resolved.&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//同步任务</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Hi!&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// Promise</span>
<span class="token comment">// Hi!</span>
<span class="token comment">// resolved</span>
</code></pre></div><h2 id="promise-实现-ajax"><a href="#promise-实现-ajax" class="header-anchor">#</a> Promise 实现 ajax</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token string">&quot;./post/1.json&quot;</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">getJSON</span><span class="token punctuation">(</span>post<span class="token punctuation">.</span>commentURL<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>
    <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">comments</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;resolved: &quot;</span><span class="token punctuation">,</span> comments<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;rejected: &quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>第一个 then 方法返回一个 promise 对象
第二个 then 方法定义了两个回调函数，等待这个新的 promise 对象的状态发生变化，如果变为 resolved 就调用第一个回调函数，变为 rejected 就调用第二个回调函数</p> <p>then 方法用于处理 Promise 成功状态回调函数，使用 catch 方法处理 Prmoise 失败状态的回调函数</p> <h2 id="catch-方法"><a href="#catch-方法" class="header-anchor">#</a> catch 方法</h2> <ul><li>指定发生错误时(包括 Promise 对象的异步操作中的错误，then 回调方法中的错误)的回调</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token class-name">Promise</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//相当于</span>
xxx<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//或</span>
xxx<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">,</span> callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//getJOSN()方法返回一个promise对象</span>
<span class="token comment">// 异步操作成功，该promise对象状态将会变为resolved，调用then方法指定的回调函数</span>
<span class="token comment">// 异步操作失败，该promise对象状态将会变为rejected，调用catch方法指定的回调来处理该错误</span>
<span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>then 方法的等价写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Promise</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rejected'</span>，error<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">//等价于</span>
<span class="token comment">//一般不要在then方法中定义rejected状态的回调函数，即不要在then方法中定义第二个参数用于错误处理，而是将其放在catch方法中</span>
<span class="token function">Promise</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rejected'</span><span class="token punctuation">,</span>error<span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="promise-all"><a href="#promise-all" class="header-anchor">#</a> Promise.all</h2> <ul><li>将多个 Promise 实例包装成一个新的 Promise 实例</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> p <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span>p1<span class="token punctuation">,</span> p2<span class="token punctuation">,</span> p3<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>p 的状态变化：
（1）只有 p1、p2、p3 的状态都变成 fulfilled，p 的状态才会变成 fulfilled，此时 p1、p2、p3 的返回值组成一个数组，传递给 p 的回调函数。
（2）只要 p1、p2、p3 之中有一个被 rejected，p 的状态就变成 rejected，此时第一个被 reject 的实例的返回值，会传递给 p 的回调函数</p> <ul><li>语法：const p = Promise.all([p1, p2, p3]);
<blockquote><ul><li>参数：</li> <li>all()方法接受一个类数组（具有 Iterator 接口）作为参数，类数组中的每个元素都是 Promise 实例</li></ul></blockquote></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> promises <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token string">&quot;/post&quot;</span> <span class="token operator">+</span> index <span class="token operator">+</span> <span class="token string">&quot;.json&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>promises<span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">posts</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h1 id="class-类"><a href="#class-类" class="header-anchor">#</a> class 类</h1> <ul><li><p>es6 以前，生成实例对象的方法是通过构造函数，这与传统面向对象语言的差异很大，于是 es6 引入了 class 类的概念作为对象模板</p></li> <li><p>es6 的 class 可看做一个语法糖，其绝大部分功能，es5 都能做到，它的引入只是让对象原型的写法更加清晰、更像面向对象编程的语法</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//es5写法</span>
<span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Point<span class="token punctuation">.</span>portotype<span class="token punctuation">.</span><span class="token function-variable function">toString</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>y<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">)</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">//es6写法</span>
<span class="token keyword">class</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>y<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">)</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">//实例化对象</span>
<span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="constructor-方法"><a href="#constructor-方法" class="header-anchor">#</a> constructor 方法</h2> <ul><li><p>类的默认方法，通过 new 命令生成对象实例时自动调用该方法。每个类都有 constructor 方法，如果没有显式定义，js 引擎会默认添加一个空的 constructor 方法</p></li> <li><p>class 类必须使用 new 调用，但普通构造函数不需要 new 就可以执行</p></li></ul> <h2 id="实例属性"><a href="#实例属性" class="header-anchor">#</a> 实例属性</h2> <ul><li>es2022 规定，实例属性除了可以写在<code>coustructor()</code>的<code>this</code>上面，也可以定义在类内部的最顶层</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//原写法</span>
<span class="token keyword">class</span> <span class="token class-name">IncreasingCounter</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>_count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>_count<span class="token operator">++</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//新写法</span>
<span class="token keyword">class</span> <span class="token class-name">IncreasingCounter</span> <span class="token punctuation">{</span>
  _count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>_count<span class="token operator">++</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h1 id="symbol"><a href="#symbol" class="header-anchor">#</a> Symbol</h1> <ul><li><p>引入背景：es5 的对象属性名都是字符串，容易造成属性名冲突。比如，使用别人提供的对象时想要为该对象添加新的方法，新方法名可能与原有方法名产生冲突。此时就需要一种机制来保证每个属性名都是独一无二的，这就是 es6 引入 Symbol 的原因</p></li> <li><p>引入 symbol 数据结构之后，js 对象的属性名现在可以有两种类型：字符串或 symbol 类型</p></li> <li><p>js 原生数据类型：undefined、null、boolean、string、Number、BigInt、Object、Symbol</p></li></ul> <h1 id="实例属性-2"><a href="#实例属性-2" class="header-anchor">#</a> 实例属性</h1> <h1 id="作为属性名"><a href="#作为属性名" class="header-anchor">#</a> 作为属性名</h1> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> mySymbol <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 第一种写法</span>
<span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
a<span class="token punctuation">[</span>mySymbol<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">&quot;Hello!&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 第二种写法</span>
<span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>mySymbol<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">&quot;Hello!&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 第三种写法</span>
<span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> mySymbol<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">&quot;Hello!&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 以上写法都得到同样结果</span>
a<span class="token punctuation">[</span>mySymbol<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// &quot;Hello!&quot;</span>
</code></pre></div><h1 id="消除魔术字符串"><a href="#消除魔术字符串" class="header-anchor">#</a> 消除魔术字符串</h1> <ul><li>魔术字符串：在代码中多次出现，与代码形成强耦合的某个具体的字符串或数值</li> <li>风格良好的代码，应尽量消除魔术字符串，由含义清晰的变量代替</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">printName</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">switch</span> <span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">case</span> <span class="token string">&quot;张三&quot;</span><span class="token operator">:</span> <span class="token comment">//魔术字符串</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;我是张三&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">printName</span><span class="token punctuation">(</span><span class="token string">&quot;张三&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*上面代码中，字符串&quot;张三&quot;就是魔术字符串，它多次出现与代码形成“强耦合”，不利于修改维护*/</span>
</code></pre></div><ul><li>解决方法一：将字符串写成变量</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>
<span class="token function">printName</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h1 id="iterator-遍历器"><a href="#iterator-遍历器" class="header-anchor">#</a> Iterator 遍历器</h1> <ul><li><p>引入背景：es6 以前能够表示“集合”的数据结构有：数组 Array 和对象 Object；es6 新增了 Map 和 Set 两种数据结构，这就需要一种统一的接口机制处理所有不同的数据结构</p></li> <li><p>遍历器 Iterator 作为一种接口，为各种不同的数据结构提供统一的访问机制，任何部署了 Iterator 接口的数据结构都可以完成遍历操作</p></li> <li><p>作用：使数据结构成员按照某种次序排列；作为 es6 新的遍历命令<code>for... of</code>的基础</p></li></ul> <blockquote><p>遍历过程</p></blockquote> <ol><li>创建一个指针对象指向当前数据结构的起始位置，遍历器对象本质就是一个指针对象</li> <li>调用指针对象的 next 方法，将指针指向数据结构的第一个成员</li> <li>再次调用指针对象的 next 方法，将指针指向数据结构的第二个成员</li> <li>重复上述过程，直到在指针指向数据结构的结束位置</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//每次调用next()方法，都会返回数据结构当前成员的信息，即一个包含value和done两个属性的对象</span>

<span class="token keyword">var</span> iterator <span class="token operator">=</span> <span class="token function">makeIterator</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&quot;a&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;b&quot;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: &quot;a&quot;, done: false }</span>
iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: &quot;b&quot;, done: false }</span>
iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: undefined, done: true }</span>
<span class="token comment">//定义一个遍历器生成函数，作用是返回一个遍历器对象</span>
<span class="token keyword">function</span> <span class="token function">makeIterator</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">next</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> index <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length
        <span class="token operator">?</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> arr<span class="token punctuation">[</span>index<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
        <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h1 id="默认-iterator-接口"><a href="#默认-iterator-接口" class="header-anchor">#</a> 默认 Iterator 接口</h1> <ul><li><p>es6 引入 Iterator 接口的目的，就是为所有数据结构提供一种统一的访问机制：<code>for...of</code>循环，某数据结构只要部署了 Iterator 接口，就称该数据结构是可遍历的(iterable)</p></li> <li><p>默认的 Iterator 接口部署在数据结构的 <code>Symbol.iterator</code> 属性,该属性本身是一个函数，当前数据结构默认的遍历器生成函数，执行该函数将返回一个遍历器</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/*
下面的对象obj是可遍历的，指向概

*/</span>
<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      <span class="token function-variable function">next</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>es6 的有些数据结构（<code>Array/Map/Set/String/TypedArray/arguments/Nodelist</code>）原生具备 Iterator 接口，可以被<code>for...of</code>循环，</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&quot;a&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;b&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;c&quot;</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">//数组具有与原生的遍历器接口，部署在数组对象的Symbol.iterator属性上，调用该属性就能得到一个遍历器对象</span>
<span class="token keyword">let</span> iter <span class="token operator">=</span> arr<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

iter<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 'a', done: false }</span>
iter<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 'b', done: false }</span>
iter<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 'c', done: false }</span>
iter<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: undefined, done: true }</span>
</code></pre></div><ul><li>不具有原生 Iterator 接口的数据结构需要自己的<code>Symbol.iterator</code>属性上部署</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">RangeIterator</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">start<span class="token punctuation">,</span> stop</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>start <span class="token operator">=</span> start<span class="token punctuation">;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>stop <span class="token operator">=</span> stop<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> index <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>start<span class="token punctuation">;</span>
    <span class="token keyword">return</span> index <span class="token operator">&lt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>stop
      <span class="token operator">?</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>start<span class="token operator">++</span><span class="token punctuation">,</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
      <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">range</span><span class="token punctuation">(</span><span class="token parameter">start<span class="token punctuation">,</span> stop</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">RangeIterator</span><span class="token punctuation">(</span>start<span class="token punctuation">,</span> stop<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> <span class="token function">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>js 对象 Object 没有原生的的 Iterator 接口，因为对象的哪个属性先遍历哪个属性后遍历是不确定的，</li></ul> <h1 id="js-遍历语法"><a href="#js-遍历语法" class="header-anchor">#</a> js 遍历语法</h1> <ul><li>for 循环</li> <li>缺点：不够简洁</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> index <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> index<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>forEach()</li> <li>缺点：无法中途跳出 forEach 循环，break 命令或 return 命令均不能奏效</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>for...in 循环</li> <li>作用：遍历键名，更适合遍历对象</li> <li>缺点：1. 数组的键名是数字 2. 遍历顺序不确定 3. 会遍历手动添加的其他键甚至包括原型链上的键</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> index <span class="token keyword">in</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>for...of 循环</li> <li>优点：解决了上述便利语法存在的问题：简洁，可与 break 等配合使用以中途退出遍历，经配置后 所有数据结构均可使用</li> <li>遍历数组时，只返回具有数组索引的属性</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span>desc <span class="token operator">=</span> <span class="token string">&quot;hello&quot;</span><span class="token punctuation">;</span>
<span class="token comment">//此时数组arr变为：Array(3)[3,5,7]</span>
<span class="token comment">//数组的对象写法为：{0:3,1:5,2:7,desc:'hello',length:3}</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">in</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;desc&quot;</span>
<span class="token punctuation">}</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">of</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//  &quot;3&quot;, &quot;5&quot;, &quot;7&quot;</span>
<span class="token punctuation">}</span>
</code></pre></div><h1 id="默认调用"><a href="#默认调用" class="header-anchor">#</a> 默认调用</h1> <ul><li>对 Array 和 Set 的解构赋值，会默认调用 Symbol.iterator</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>
</code></pre></div><ul><li><p>扩展运算符</p></li> <li><p>yield</p></li></ul> <h1 id="遍历器对象的其他方法"><a href="#遍历器对象的其他方法" class="header-anchor">#</a> 遍历器对象的其他方法</h1> <ul><li>return() 方法</li> <li>调用时机：<code>for...of</code>循环提前退出时调用 return()方法</li> <li>应用场景：对象在完成遍历之前需要清理或释放资源</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>
<span class="token keyword">function</span> <span class="token function">readLines</span><span class="token punctuation">(</span><span class="token parameter">file</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token punctuation">{</span>
        <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
          <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token literal-property property">done</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
          <span class="token comment">//文件对象遍历过程中异常退出，关闭文件</span>
          file<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token literal-property property">done</span><span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>会触发<code>return()</code>方法的情况</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//输出文件的第一行后，break退出遍历，后关闭文件</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> line <span class="token keyword">of</span> <span class="token function">readLinesSync</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 关闭文件后再抛出错误</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> line <span class="token keyword">of</span> <span class="token function">readLinesSync</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h1 id="proxy-代理"><a href="#proxy-代理" class="header-anchor">#</a> Proxy 代理</h1> <ul><li><p>用于修改某些操作的默认行为</p></li> <li><p>proxy 对象创建一个对象代理，从而实现基本操作的拦截和自定义（如属性查找、赋值、枚举、函数调用等）</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 语法</span>
<span class="token keyword">const</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>targetObj<span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>参数</p> <ul><li>targetObj:要使用 Proxy 包装的目标对象</li> <li>handler:函数（通常情况下），定义了在执行各种操作时代理 p 的行为</li></ul></blockquote> <ul><li>作用：在目标对象前架设一层拦截外界对该对象的访问，都必须先通过这层拦截，因而提供了一种机制对外界的访问进行过滤盒改写</li></ul> <h2 id="handler-函数方法"><a href="#handler-函数方法" class="header-anchor">#</a> handler 函数方法</h2> <h2 id="get"><a href="#get" class="header-anchor">#</a> get</h2> <ul><li>作用：拦截对象的读取属性操作</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token function-variable function">get</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> receiver</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;called: &quot;</span> <span class="token operator">+</span> prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//读取属性之前，打印待读取的属性名</span>
      <span class="token keyword">return</span> <span class="token number">10</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &quot;called: a&quot;; ouptut 10</span>
</code></pre></div><h2 id="set"><a href="#set" class="header-anchor">#</a> set</h2> <ul><li>作用：用于拦截设置属性值的操作</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token function-variable function">set</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> value<span class="token punctuation">,</span> receiver</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      target<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;property set: &quot;</span> <span class="token operator">+</span> prop <span class="token operator">+</span> <span class="token string">&quot; = &quot;</span> <span class="token operator">+</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;a&quot;</span> <span class="token keyword">in</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>

p<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// &quot;property set: a = 10&quot;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;a&quot;</span> <span class="token keyword">in</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span>
</code></pre></div><h2 id="has"><a href="#has" class="header-anchor">#</a> has</h2> <ul><li><p>针对 in 操作符的代理方法</p></li> <li><p>可拦截的操作</p> <blockquote><ul><li>属性查询：foo in proxy</li> <li>继承属性查询：foo in Object.create(proxy)</li> <li>with 检查: with(proxy) { (foo); }</li></ul></blockquote></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token function-variable function">has</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;called: &quot;</span> <span class="token operator">+</span> prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;a&quot;</span> <span class="token keyword">in</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &quot;called: a&quot;; outputs true</span>
</code></pre></div><h2 id="defineproperty"><a href="#defineproperty" class="header-anchor">#</a> defineProperty</h2> <ul><li>作用：拦截对目标对象的 Object.defineProperty() 操作</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token function-variable function">defineProperty</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> descriptor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;called: &quot;</span> <span class="token operator">+</span> prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> desc <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> <span class="token string">&quot;a&quot;</span><span class="token punctuation">,</span> desc<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &quot;called: a&quot;</span>
</code></pre></div><h2 id="deleteproperty"><a href="#deleteproperty" class="header-anchor">#</a> deleteProperty</h2> <ul><li>作用：拦截 delete 操作</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token function-variable function">deleteProperty</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> prop</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;called: &quot;</span> <span class="token operator">+</span> prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">delete</span> p<span class="token punctuation">.</span>a<span class="token punctuation">;</span> <span class="token comment">// &quot;called: a&quot;</span>
</code></pre></div><h1 id="reflect-对象"><a href="#reflect-对象" class="header-anchor">#</a> Reflect 对象</h1> <ul><li>将 Object 对象的一些属于语言内部的方法放在 Reflect 对象上，从 Reflect 对象上拿到语言内部的方法</li> <li>修改某些 Object 方法的返回结果是变得合理</li> <li>将某些命令式 Object 操作（如<code>property in Obj/delete obj[name]</code>）变为函数行为<code>(Reflect.has(Obj,name))/Reflect.deleteProperty(Obj, property)</code> <blockquote><p>es5 写法</p></blockquote></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">//访问与删除对象元素</span>
<span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token string">&quot;name&quot;</span> <span class="token keyword">in</span> obj<span class="token punctuation">;</span>
<span class="token keyword">delete</span> obj<span class="token punctuation">.</span>age<span class="token punctuation">;</span>
<span class="token comment">//实例化一个构造函数对象</span>
<span class="token keyword">function</span> <span class="token function">Fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> fn <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>es6 写法</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> res <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> delete_sign <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">deleteProerty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">&quot;age&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> fn2 <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">constructr</span><span class="token punctuation">(</span>Fn<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>与 es6 的新增方法等更方便灵活地编程</li></ul> <h2 id="reflect-对象静态方法"><a href="#reflect-对象静态方法" class="header-anchor">#</a> Reflect 对象静态方法</h2> <ul><li>Reflect 对象的方法与 Proxy 对象的方法一一对应，后者的方法都能在前者上找到对应的方法，这就让 Proxy 对选哪个更加方便的调用对应的 Reflect 方法完成默认行为</li></ul> <h3 id="apply-方法"><a href="#apply-方法" class="header-anchor">#</a> apply 方法</h3> <ul><li><p>语法：Reflect.apply(target, thisArg, args)</p> <blockquote><p>参数</p> <ul><li>target:目标函数</li> <li>thisArg:目标函数绑定的 this 对象</li> <li>args:target 函数调用时传递的参数，类数组对象</li></ul></blockquote></li> <li><p>es5 写法：先指定方法，再调用 apply</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1.72</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>es6 写法:先传递 apply，再指定方法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Reflect</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>floor<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1.72</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>静态扫描时，Math.floor 没有被执行，运行时再动态将 Math.floor 作为参数传递</p></blockquote> <ul><li>实际应用</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//es5写法</span>
<span class="token keyword">let</span> price <span class="token operator">=</span> <span class="token number">101.5</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>price <span class="token operator">&gt;</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  price <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>price<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
  price <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>price<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//es6写法</span>
<span class="token function">Reflect</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>price <span class="token operator">&gt;</span> <span class="token number">100</span> <span class="token operator">?</span> Math<span class="token punctuation">.</span>floor <span class="token operator">:</span> Math<span class="token punctuation">.</span>ceil<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>price<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="construct-方法"><a href="#construct-方法" class="header-anchor">#</a> construct 方法</h3> <ul><li><p>创建类实例</p></li> <li><p>es5 写法</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> date <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">construct</span><span class="token punctuation">(</span>Date<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="defineproperty-方法"><a href="#defineproperty-方法" class="header-anchor">#</a> defineProperty 方法</h3> <ul><li>es5 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> student <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> res <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>student<span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">&quot;张三&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{name:'张三'}</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> res <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>student<span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">&quot;张三&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
</code></pre></div><ul><li>两个方法=在效果上一样，但一个返回对象本身，一个返回布尔值</li></ul> <h3 id="deleteproperty-方法"><a href="#deleteproperty-方法" class="header-anchor">#</a> deleteProperty()方法</h3> <ul><li><p>语法：deleteProperty(target, name, receiver)</p> <blockquote><p>作用：相当于<code>delete obj[name]</code>，用于删除对象的属性
返回值：Boolean 值。删除成功或被删除的属性不存在则返回 true，删除失败返回 false</p></blockquote></li> <li><p>es5 写法</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> Obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">delete</span> Obj<span class="token punctuation">.</span>age<span class="token punctuation">;</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>Reflect<span class="token punctuation">.</span><span class="token function">deleteProperty</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;age&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="getprototypeof-方法"><a href="#getprototypeof-方法" class="header-anchor">#</a> getPrototypeOf 方法</h3> <ul><li><p>返回指定对象的原型</p></li> <li><p>es5 写法</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> res <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> res <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="get-方法"><a href="#get-方法" class="header-anchor">#</a> get()方法</h3> <ul><li>语法：get(target, name, receiver)</li> <li>作用：查找并返回 target 对象的 name 属性，如果没有就返回 undefined</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> Obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
  <span class="token keyword">get</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">我是</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,今年</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">岁</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
Reflect<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//10</span>
Reflect<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;age&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//张三</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Reflect<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;say&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//我是张三，今年10岁</span>
</code></pre></div><h3 id="set-方法"><a href="#set-方法" class="header-anchor">#</a> set()方法</h3> <ul><li>语法：set(target, name, value,receiver)</li> <li>作用：设置 target 对象的 name 属性值为 value</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> Obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
  <span class="token keyword">set</span> <span class="token function">resetAge</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
Obj<span class="token punctuation">.</span>age<span class="token punctuation">;</span> <span class="token comment">//10</span>

Reflect<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;age&quot;</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Obj<span class="token punctuation">.</span>age<span class="token punctuation">;</span> <span class="token comment">//20</span>
</code></pre></div><h3 id="has-方法"><a href="#has-方法" class="header-anchor">#</a> has()方法</h3> <ul><li>语法：has(target, name)</li> <li>作用：相当于<code>name in obj</code>中的<code>in</code>运算符，判断对象中是否有指定的属性</li> <li>es5 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> Obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token string">&quot;age&quot;</span> <span class="token keyword">in</span> Obj<span class="token punctuation">;</span> <span class="token comment">//true</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>Reflect<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>Obj<span class="token punctuation">,</span> <span class="token string">&quot;age&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
</code></pre></div><h3 id="ownkeys-方法"><a href="#ownkeys-方法" class="header-anchor">#</a> ownKeys()方法</h3> <ul><li>返回一个由目标对象的属性键组成的数组，</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> myObject <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">foo</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
  <span class="token literal-property property">bar</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
  <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">&quot;baz&quot;</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
  <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">&quot;bing&quot;</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>es5 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyNames</span><span class="token punctuation">(</span>myObject<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ['foo', 'bar']</span>

Object<span class="token punctuation">.</span><span class="token function">getOwnPropertySymbols</span><span class="token punctuation">(</span>myObject<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//[Symbol(baz), Symbol(bing)]</span>
</code></pre></div><ul><li>es6 写法</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>Reflect<span class="token punctuation">.</span><span class="token function">ownKeys</span><span class="token punctuation">(</span>myObject<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ['foo', 'bar', Symbol(baz), Symbol(bing)]</span>
</code></pre></div><blockquote><p>等同于 Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))</p></blockquote> <h2 id="实例-观察者模式"><a href="#实例-观察者模式" class="header-anchor">#</a> 实例：观察者模式</h2> <ul><li>观察者模式：函数自动观察数据对象，一旦对象发生变化，函数自动执行</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//定义一个集合，存储所有观察者函数</span>
<span class="token keyword">const</span> queueObservers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//该函数向集合中添加观察者函数</span>
<span class="token keyword">function</span> <span class="token function">observer</span><span class="token punctuation">(</span><span class="token parameter">Fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  queueObservers<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>Fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 返回一个原始对象的 Proxy 代理，拦截赋值操作，触发充当观察者的各个函数。</span>
<span class="token keyword">function</span> <span class="token function">observable</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> property<span class="token punctuation">,</span> value<span class="token punctuation">,</span> receiver<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> result <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>targetObj<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> receiver<span class="token punctuation">)</span><span class="token punctuation">;</span>
      queuedObservers<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">observer</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">observers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> result<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>上面 proxy 代理的内部逻辑是，当对象属性的值被修改时，触发 set 函数，首先使用 Reflect.set()修改该属性的值，然后遍历集合中的每一个观察者函数并执行，，最后返回布尔值代表对象的属性值是否修改成功</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//</span>
<span class="token keyword">const</span> person <span class="token operator">=</span> <span class="token function">observable</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 定义一个观察者函数，并加入集合</span>
<span class="token keyword">function</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>person<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>person<span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">observe</span><span class="token punctuation">(</span>print<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//对对象的属性进行赋值操作，触发set函数的执行</span>
person<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&quot;李四&quot;</span><span class="token punctuation">;</span>
</code></pre></div><h1 id="generator-函数"><a href="#generator-函数" class="header-anchor">#</a> Generator 函数</h1> <ul><li>一种异步编程解决方案，形式上 Generator 函数是一个普通函数，但具有两个特征
<blockquote><ul><li>function 关键字与函数名之间有一个星号</li> <li>函数体内部使用 yield 表达式，用于定义不同的内部状态</li></ul></blockquote></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token operator">*</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">yield</span> <span class="token string">&quot;a&quot;</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span> <span class="token string">&quot;b&quot;</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span> <span class="token string">&quot;c&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> val <span class="token keyword">of</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ['a','b','c']</span>
</code></pre></div><ul><li>Generator 函数的调用与普通函数的写法一样，在函数名后面加一对圆括号</li> <li>Generator 函数调用之后，该函数并不执行，返回的不是函数运行的结果，而是一个指向内部状态的指针对象（遍历器对象 Iterator Object）</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">myGenerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">yield</span> <span class="token string">&quot;NO1&quot;</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span> <span class="token string">&quot;NO2&quot;</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token string">&quot;ending&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token function">myGenerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>上面代码中，定义一个 Generator 函数，其内部有两个 yield 表达式和 return 语句，该函数有三个状态：NO1/NO2/ending</p></blockquote> <ul><li>Generator 函数调用之后，需要调用其 next()方法使指针移向下一个状态，直到遇到 yield 或 return 语句（也就是说 Generator 函数是分段执行的，yield 表达式是暂停执行的标记，而 next 方法可以恢复执行）</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>obj<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { value: 'NO1', done: false }</span>

obj<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { value: 'NO2', done: false }</span>

obj<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { value: 'ending', done: true }</span>

obj<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { value: undefined, done: true }</span>
</code></pre></div><ul><li>注意：ES6 没有规定，function 关键字与函数名之间的星号，写在哪个位置。这导致下面的写法都能通过</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token operator">*</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ··· <span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token operator">*</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ··· <span class="token punctuation">}</span>
<span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ··· <span class="token punctuation">}</span>
<span class="token keyword">function</span><span class="token operator">*</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ··· <span class="token punctuation">}</span>
</code></pre></div><h2 id="yield-表达式"><a href="#yield-表达式" class="header-anchor">#</a> yield 表达式</h2> <ul><li><p>next 方法执行逻辑</p></li> <li><p>yield 表达式只能用在 Generator 函数里面，用在其他地方都会报错</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">yield</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// SyntaxError: Unexpected number</span>
</code></pre></div><ul><li>yield 表达式如果用在另一个表达式之中，必须放在圆括号里面</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello'</span> <span class="token operator">+</span> <span class="token keyword">yield</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// SyntaxError</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello'</span> <span class="token operator">+</span> <span class="token keyword">yield</span> <span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// SyntaxError</span>

  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello'</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token keyword">yield</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello'</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token keyword">yield</span> <span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>yield 表达式用作函数参数或放在赋值表达式的右边，可以不加括号</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">foo</span><span class="token punctuation">(</span><span class="token keyword">yield</span> <span class="token string">&quot;a&quot;</span><span class="token punctuation">,</span> <span class="token keyword">yield</span> <span class="token string">&quot;b&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
  <span class="token keyword">let</span> input <span class="token operator">=</span> <span class="token keyword">yield</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>把 Generator 赋值给对象的 Symbol.iterator 属性，从而使得该对象具有 Iterator 接口</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> myIterable <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
myIterable<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token operator">*</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">yield</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span> <span class="token number">2</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token punctuation">[</span><span class="token operator">...</span>myIterable<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3]</span>
</code></pre></div><h2 id="next-方法"><a href="#next-方法" class="header-anchor">#</a> next()方法</h2> <ul><li>next 方法可以携带一个参数作为上一个 yield 表达式的返回值</li> <li>next 携带的参数可用于在 Generator 函数开始运行之后，向函数体内部注入值，从而在 Generator 函数的不同运行阶段调整函数行为</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 定义一个可以无限运行的Generator函数</span>
<span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token boolean">true</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> reset <span class="token operator">=</span> <span class="token keyword">yield</span> i<span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>reset<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      i <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> g <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

g<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 0, done: false }</span>
g<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 1, done: false }</span>
g<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 0, done: false }</span>
</code></pre></div><blockquote><p>上面代码中，如果 next 方法没有参数，每次运行到 yield 表达式，变量 reset 的值总是 undefined。
当 next 方法带一个参数 true 时，变量 reset 就被重置为这个参数（即 true）执行 i=-1，下一轮循环就会从-1 开始递增。</p></blockquote> <h1 id="for-of-循环"><a href="#for-of-循环" class="header-anchor">#</a> for...of 循环</h1> <ul><li><p>使用 for...of 循环自动遍历 Generator 函数运行时生成的 Iterator 对象，且此时不再需要调用 next 方法</p></li> <li><p>一旦 next 方法的返回对象的 done 属性为 true，for...of 循环就会终止且不包含返回对象，</p></li> <li><p>利用 Generator 函数可以对任意对象完成遍历。原生 js 对象没有遍历接口，无法使用<code>for...of</code>循环</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span><span class="token operator">*</span> <span class="token function">objEntries</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">let</span> propKeys<span class="token operator">=</span>
<span class="token punctuation">}</span>
</code></pre></div><h1 id="异步"><a href="#异步" class="header-anchor">#</a> 异步</h1> <ul><li>js 语言的执行环境是单线程的，故异步编程对于 js 语言很重要
es6 前的异步编程方法</li></ul> <ol><li>回调函数</li> <li>事件监听</li> <li>发布/订阅</li> <li>Promise 对象</li></ol> <h1 id="严格模式"><a href="#严格模式" class="header-anchor">#</a> 严格模式</h1> <ul><li>变量先声明再使用</li> <li>函数参数不能有同名属性，负责报错</li> <li>不能使用 with 语句</li> <li>不能赋值只读属性</li></ul> <h1 id="模块语法"><a href="#模块语法" class="header-anchor">#</a> 模块语法</h1> <ul><li><p>es6 以前，js 已知没有模块体系，无法将一个大工程拆分为互相依赖的小文件在用简单的方法拼接起来，但其他语言都有这项功能（如 python 的 import、Ruby 的 require），这对开发大型复杂的项目形成了巨大的障碍</p></li> <li><p>es6 前社区制定了一些模块加载方案主要是 commonJS（用于服务器）和 AMD（用于浏览器），es6 实现了模块功能并可以完全替代上面两种规范，成为浏览器和服务器通用的模块解决方案</p></li> <li><p>es6 模块的设计思想是尽量静态化，使编译时就能确定模块之间的依赖关系以及输入和输出的关系。CommonJs 和 AMD 都只能在运行时才能确定模块间的依赖关系</p></li></ul> <h2 id="es6-模块设计初衷"><a href="#es6-模块设计初衷" class="header-anchor">#</a> es6 模块设计初衷</h2> <ul><li>静态化：使编译时就能确定模块的依赖关系以及输入输出的变量</li> <li>代码组织问题：随着代码量不断增加，将所有代码写进一个文件中会难以组织和维护，将代码从一个大文件拆分为若干个相互依赖的小文件</li> <li>浏览器和服务器的通用模块解决方案：es6 之前，js 没有官方的模块系统，社区中存在 commonJS 和 AMD 两种模块规范，但两者都有各自的局限，分别是用于浏览器和服务器</li> <li>简洁性：es6 通过 export 和 import 两个关键字就能完成模块的输入输出操作，使模块的使用非常直观和方便</li></ul> <h2 id="export-命令"><a href="#export-命令" class="header-anchor">#</a> export 命令</h2> <ul><li><p>es6 模块主要由两个命令构成<code>export</code>(规定模块的对外接口)和<code>import</code>(输入其他模块提供的功能)</p></li> <li><p>一个模块就是一个独立文件，该文件内部所有变量没有经过 export 暴露，外界就无法获取</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//test.js</span>
<span class="token comment">/*
export写法：
*/</span>
<span class="token keyword">export</span> <span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">var</span> age <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">var</span> year <span class="token operator">=</span> <span class="token number">1999</span><span class="token punctuation">;</span>

<span class="token comment">//等价于</span>
<span class="token comment">//一般优先考虑使用下面的写法，因为这样就可以在脚本尾部一眼看出该文件向外暴露了哪些变量</span>
<span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> age <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> year <span class="token operator">=</span> <span class="token number">1999</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> age<span class="token punctuation">,</span> year <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>export 命令规定的对外接口必须与模块内部变量建立一一对应关系，</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//报错</span>
<span class="token keyword">export</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">//报错:直接向外暴露数字1（此处相当于直接使用了变量m），没有一一对应关系</span>
<span class="token keyword">var</span> m<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> m<span class="token punctuation">;</span>

<span class="token comment">//正确写法一：</span>
<span class="token keyword">export</span> <span class="token keyword">var</span> m<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">//正确写法二：</span>
<span class="token keyword">var</span> m<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span>m<span class="token punctuation">}</span>
<span class="token comment">//正确性写法三：</span>
<span class="token keyword">var</span> n<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span>n <span class="token keyword">as</span> m<span class="token punctuation">}</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 报错</span>
<span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">export</span> f<span class="token punctuation">;</span>

<span class="token comment">// 正确</span>
<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 正确</span>
<span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span>f<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>使用 as 关键字重命名</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">v1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">v2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span>
  v1 <span class="token keyword">as</span> streamV1<span class="token punctuation">,</span>
  v2 <span class="token keyword">as</span> streamV2<span class="token punctuation">,</span>
  v2 <span class="token keyword">as</span> streamLatestVersion
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>上面代码中<strong>函数 v2</strong>使用不同的名字输出了两次</p></blockquote> <ul><li>export 命令能够向外暴露三种接口：函数 Function、类 Class、变量 variable</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">printName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'张三'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token operator">=</span><span class="token string">&quot;person&quot;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>export 命令可出现在模块的任何位置，但如果<strong>位于块级作用域内</strong>就会报错。因为处于<strong>条件代码块中</strong>就没法做静态优化，违背了 es6 模块的设计初衷</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//export语句放在了块级作用域之中，将会报语法错误</span>
<span class="token keyword">function</span> <span class="token function">emptyFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token string">&quot;xx&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// import语句同样不能放在块级作用域中</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">import</span> <span class="token punctuation">{</span> foo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;module1&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
  <span class="token keyword">import</span> <span class="token punctuation">{</span> foo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;module2&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="import-语句"><a href="#import-语句" class="header-anchor">#</a> import 语句</h2> <ul><li>import 语句具有提升效果，会提升到整个模块头部首先执行</li> <li>使用 export 命令定义了模块的对外接口后，其他 js 文件就可以通过 import 命令加载改模块</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//可使用export default命令解除该限制</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> age <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./test.js&quot;</span><span class="token punctuation">;</span>
<span class="token comment">//为输入的变量重命名</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> myName <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./test.js&quot;</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="注意-关于-export-和-import-方法名一致的问题"><a href="#注意-关于-export-和-import-方法名一致的问题" class="header-anchor">#</a> 注意：关于 export 和 import 方法名一致的问题</h3> <p>目录结构</p> <div class="language- extra-class"><pre class="language-text"><code>|- data.js    向外export
|- index.js   从外面import
</code></pre></div><p><strong>第一种：export 分别暴露，import 分别导入</strong></p> <ul><li>data.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> age <span class="token operator">=</span> <span class="token number">12</span><span class="token punctuation">;</span>

<span class="token comment">//此处相当于向外面暴露了一个对象，该对象有属性name和age</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> age <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>能不能将 export 命令理解为就是向外暴露了一个对象，不管是不是 default 暴露，其他模块引入时都是将该对象进行了引入</p></blockquote> <ul><li>index.js</li></ul> <blockquote><p>分别导入时，大括号中的变量名必须与被导入模块对外接口的名称相同，这就需要使用该模块的开发者事先知道这些接口名称
通俗的来说，就是 data.js 向外暴露了 name 和 age 两个变量，index.js 要分别导入，就只能使用 name 和 age 两个变量</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> age <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;data.js&quot;</span><span class="token punctuation">;</span>
<span class="token comment">// 或使用as关键字重命名</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> myName<span class="token punctuation">,</span> age <span class="token keyword">as</span> myAge <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;data.js&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>第二种：export 默认暴露，import 默认导入</strong></p> <ul><li>data.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> name<span class="token punctuation">;</span>
</code></pre></div><ul><li>index.js</li></ul> <blockquote><p>由于 data.js 向外默认暴露了一个变量，index.js 导入时可随便进行重命名</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> myName <span class="token keyword">from</span> <span class="token string">&quot;./data.js&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>第三种：export 默认暴露和分别暴露，import 同时导入默认接口和其他接口</strong></p> <ul><li>data.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// ···</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">each</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> iterator<span class="token punctuation">,</span> context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// ···</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> each <span class="token keyword">as</span> forEach <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>index.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> _<span class="token punctuation">,</span> <span class="token punctuation">{</span> each<span class="token punctuation">,</span> forEach <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;lodash&quot;</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="其他注意事项"><a href="#其他注意事项" class="header-anchor">#</a> 其他注意事项</h3> <ul><li>使用 import 命令导入的变量（只读）不允许被修改</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> a <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./test.js&quot;</span><span class="token punctuation">;</span>
<span class="token comment">//a作为其他文件向外暴露的接口，如果对齐重新赋值就会报错，</span>
a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>import 语句会执行所加载的模块,下面一行代码只会执行<code>mock/index.js</code>文件但不会导入任何变量</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token string">&quot;./mock/index.js&quot;</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>多次加载同一句 import 语句只会执行一次，下面代码加载了两次<code>mock/index.js</code>但是只会执行一次该文件</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token string">&quot;./mock/index.js&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token string">&quot;./mock/index.js&quot;</span><span class="token punctuation">;</span>
</code></pre></div><ul><li>import 语句是静态执行（编译时）的，不能使用表达式和变量，因为这些只能在运行时得到结果</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 报错：使用了表达式</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token string">'f'</span> <span class="token operator">+</span> <span class="token string">'oo'</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'my_module'</span><span class="token punctuation">;</span>

<span class="token comment">// 报错：先赋值再import</span>
<span class="token keyword">let</span> module <span class="token operator">=</span> <span class="token string">'my_module'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> foo <span class="token punctuation">}</span> from module<span class="token punctuation">;</span>

<span class="token comment">// 报错:使用了if结构</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">import</span> <span class="token punctuation">{</span> foo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'module1'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
  <span class="token keyword">import</span> <span class="token punctuation">{</span> foo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'module2'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="模块的整体加载"><a href="#模块的整体加载" class="header-anchor">#</a> 模块的整体加载</h3> <p>目录结构</p> <div class="language- extra-class"><pre class="language-text"><code>|- data.js    向外暴露变量
|- index.js   导入变量
</code></pre></div><ul><li>data.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">area</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token string">&quot;10&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">circumference</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token string">&quot;20&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>index.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 方法一：逐一加载</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> area<span class="token punctuation">,</span> circumference <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./data.js&quot;</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;圆面积：&quot;</span> <span class="token operator">+</span> <span class="token function">area</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;圆周长：&quot;</span> <span class="token operator">+</span> <span class="token function">circumference</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 方法二：整体加载,此处相当于是把data.js文件向外暴露的对象中的方法复制到了一个新的对象身上，而该对象在index.js中可以随意命名</span>
<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> circle <span class="token keyword">from</span> <span class="token string">&quot;./circle&quot;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;圆面积：&quot;</span> <span class="token operator">+</span> circle<span class="token punctuation">.</span><span class="token function">area</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;圆周长：&quot;</span> <span class="token operator">+</span> circle<span class="token punctuation">.</span><span class="token function">circumference</span><span class="token punctuation">(</span><span class="token number">14</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="export-与-import-混合使用"><a href="#export-与-import-混合使用" class="header-anchor">#</a> export 与 import 混合使用</h3> <p>在一个模块中先输入后输出同一个模块，import 语句和 export 语句可以写在一起（写在一起时，模块实际上并没有别导入当前文件，只是相当于对外转发了这两个接口）</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;my_module&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 可以简单理解为</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;my_module&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="有什么用-接口聚合"><a href="#有什么用-接口聚合" class="header-anchor">#</a> 有什么用：接口聚合</h4> <p>假设当前某项目的结构如下：</p> <div class="language- extra-class"><pre class="language-text"><code>|- 根目录
  |- components
    |- School.vue
    |- Student.vue
    |- Other.vue
  |- App.vue
</code></pre></div><p>现在的情况是，<code>App.vue</code>想要同时引入 components 文件夹下的三个子组件，于是，App.vue 中就应该这样写</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> Student <span class="token keyword">from</span> <span class="token string">'./components/Student.vue'</span><span class="token punctuation">,</span>
<span class="token keyword">import</span> School <span class="token keyword">from</span> <span class="token string">'./components/School.vue'</span><span class="token punctuation">,</span>
<span class="token keyword">import</span> Other <span class="token keyword">from</span> <span class="token string">'./components/Other.vue'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span><span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span><span class="token string">'App'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">components</span><span class="token operator">:</span><span class="token punctuation">{</span>
    Student<span class="token punctuation">,</span>School<span class="token punctuation">,</span>Other
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>当需要引入的文件较少时，这种情况还好，当需要引入更多的文件时，这里的 import 语句就会很多，这不利于项目的维护</p> <p><strong>解决该问题</strong>
在<code>components</code>文件夹下建立文件<code>index.js</code>,并写入下面内容</p> <ul><li>目录结构</li></ul> <div class="language- extra-class"><pre class="language-text"><code>|- 根目录
  |- components
    |- index.js
    |- School.vue
    |- Student.vue
    |- Other.vue
  |- App.vue
</code></pre></div><ul><li>components/index.js</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token punctuation">{</span> <span class="token keyword">default</span> <span class="token keyword">as</span> Student <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./Student&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> <span class="token keyword">default</span> <span class="token keyword">as</span> School <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./School&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> <span class="token keyword">default</span> <span class="token keyword">as</span> Other <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./Other&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p>于是<code>App.vue</code>中就需要用下面的方法进行<code>import</code></p> <ul><li>App.vue</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> Student<span class="token punctuation">,</span> School<span class="token punctuation">,</span> Other <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./components&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&quot;App&quot;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">components</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    Student<span class="token punctuation">,</span>
    School<span class="token punctuation">,</span>
    Other<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>于是，components 下的子组件就能得到统一的管理，利于项目的维护</p> <h2 id="export-default-命令"><a href="#export-default-命令" class="header-anchor">#</a> export default 命令</h2> <ul><li><p>一个模块只能有一个默认输出，因此<code>export default</code>命令一个模块中只能使用一次</p></li> <li><p><code>export default</code>命令本质只是输出了一个叫做 default 的变量，</p></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/*test.js*/</span>
<span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span>name <span class="token keyword">as</span> <span class="token keyword">default</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">//相当于</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> name

<span class="token comment">/*main.js*/</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span><span class="token keyword">default</span> <span class="token keyword">as</span> name<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./text.js'</span>
<span class="token comment">//等价于：import</span>
<span class="token keyword">import</span> name <span class="token keyword">from</span> <span class="token string">'./test.js'</span>
</code></pre></div><ul><li><code>export default</code>命令后面不能跟变量声明语句，因为<code>export default variable</code>的含义是将变量 variable 的值赋给变量 default，这与 export 语句的用法不同</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//错误写法</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">var</span> a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>

<span class="token comment">//正确写法</span>
<span class="token keyword">var</span> a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> a<span class="token punctuation">;</span>

<span class="token comment">//export语句正确写法</span>
<span class="token keyword">export</span> <span class="token keyword">var</span> a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="import"><a href="#import" class="header-anchor">#</a> import()</h2> <h3 id="引入背景"><a href="#引入背景" class="header-anchor">#</a> 引入背景</h3></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"></div></div>
    <script src="/awesome-notebook/assets/js/app.5520c9b0.js" defer></script><script src="/awesome-notebook/assets/js/2.778bb4ad.js" defer></script><script src="/awesome-notebook/assets/js/1.50b457b8.js" defer></script><script src="/awesome-notebook/assets/js/25.dedb1585.js" defer></script>
  </body>
</html>
